iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 15
1
Mobile Development

程式初學:Android與Kotlin系列 第 15

Day 15--天氣app(一) Open Data API,JSON

  • 分享至 

  • xImage
  •  

接下來想實做一款簡易天氣預報app

Open Data

首先要取得資料內容,搜尋天氣opendata
https://opendata.cwb.gov.tw/user/authkey

API須要授權碼才能向氣象局取得資料,這邊登入後就按[取得授權碼]

把這組授權碼拿到
https://opendata.cwb.gov.tw/dist/opendata-swagger.html#/%E9%A0%90%E5%A0%B1/get_v1_rest_datastore_F_C0032_001
右方有一個Try it out 按下去,在氣象開放資料平台會員授權碼
欄位輸入

再拉下來一點,按下Execute按鈕,就會得到api的Request Url與Response

以瀏覽器或是直接用 https://jsoneditoronline.org/
開啓得到的Request Url就可以看到資料

繼續看氣象局的網頁下方,也有把JSON格式整理出來了,不過好像還是用jsoneditoronline.org清楚一點

...

以上是在中央氣象局的申請方式,如果想要篩選一些資訊,可以在這邊的網頁調整,例如

後來發現可以直接在政府資料開放平臺找到不用自己申請授權碼的網址... https://data.gov.tw/dataset/6069


按下api就會直接得到包含授權碼rdec-key-123-45678-011121314的網址
https://opendata.cwb.gov.tw/api/v1/rest/datastore/F-C0032-001?Authorization=rdec-key-123-45678-011121314

JSON

什麼是JSON
一種資料交換語言,或者我理解爲一種格式,包裝資料並可在網路傳輸與可讓其它程式解析

可使用基本資料類型,支援純數字,字串,boolean,array,object等

結構主要包含二種

object

以大括號{}包裝,格式是key與value配對,中間以冒號分隔
{key:value}
多個object以逗號分隔
{key:value,key:value,key:value}

key必須爲字串格式,如"key"

value可以是任何 JSON 資料格式,如字串(string)、數值(number)、true、false、null、對象(object)或者陣列(array)
範例
{"name":"Sophia","age":"20"}

array

以中括號[]包裝,格式是各種value的有序集合,以逗號分隔
範例[object,數值,字串]
[{"name":"Sophia","age":"20"},100,"address"]

一個有效的JSON文件的根節點必須是一個物件或一個陣列
所以通常有一個最外層包起來,例如氣象局的天氣資料

object{3},就是以{}把全部資料包成一個object
然後裡面有3個key-value以逗號分隔
{"success":"true","result":"{2個key-value對}","records":"{2個key-value對}"}

  1. "success":"true"
  2. "result":"{2個object}"
  3. "records":"{2個object}"

參考資料
http://www.json.org/json-zh.html
https://j796160836.pixnet.net/blog/post/30530326-%E7%9E%AD%E8%A7%A3json%E6%A0%BC%E5%BC%8F
https://www.fooish.com/json/data-format.html

data class

有了資料來源,就可以拿來程式裡面用了
利用之前提到的插件JsonToKotlinClass來轉換爲data class

在專案中開一個WeatherData.kt檔案

右鍵選generate開啓Kotlin data class from JSON
Class Name欄位輸入WeatherData

右鍵開啓Retrieve content from Http Url
把前面得到的request url輸入進去,按OK

最後就會產生data class WeatherData的程式碼
對照前面的object,包含3個key-value
`{"success":"true","result":"{2個key-value對}","records":"{2個key-value對}"}

data class WeatherData(
    @SerializedName("records")
    val records: Records = Records(),
    @SerializedName("result")
    val result: Result = Result(),
    @SerializedName("success")
    val success: String = "" // true
)

因爲records與result的value又爲object包含其它資料
所以完整如下

data class WeatherData(
    @SerializedName("records")
    val records: Records = Records(),
    @SerializedName("result")
    val result: Result = Result(),
    @SerializedName("success")
    val success: String = "" // true
) {
    data class Records(
        @SerializedName("datasetDescription")
        val datasetDescription: String = "", // 三十六小時天氣預報
        @SerializedName("location")
        val location: List<Location> = listOf()
    ) {
        data class Location(
            @SerializedName("locationName")
            val locationName: String = "", // 嘉義縣
            @SerializedName("weatherElement")
            val weatherElement: List<WeatherElement> = listOf()
        ) {
            data class WeatherElement(
                @SerializedName("elementName")
                val elementName: String = "", // Wx
                @SerializedName("time")
                val time: List<Time> = listOf()
            ) {
                data class Time(
                    @SerializedName("endTime")
                    val endTime: String = "", // 2020-08-07 18:00:00
                    @SerializedName("parameter")
                    val parameter: Parameter = Parameter(),
                    @SerializedName("startTime")
                    val startTime: String = "" // 2020-08-07 12:00:00
                ) {
                    data class Parameter(
                        @SerializedName("parameterName")
                        val parameterName: String = "", // 多雲午後短暫雷陣雨
                        @SerializedName("parameterUnit")
                        val parameterUnit: String = "", // 百分比
                        @SerializedName("parameterValue")
                        val parameterValue: String = "" // 22
                    )
                }
            }
        }
    }

    data class Result(
        @SerializedName("fields")
        val fields: List<Field> = listOf(),
        @SerializedName("resource_id")
        val resourceId: String = "" // F-C0032-001
    ) {
        data class Field(
            @SerializedName("id")
            val id: String = "", // datasetDescription
            @SerializedName("type")
            val type: String = "" // String
        )
    }
}

上一篇
Day 14--Intent Activity,Back Stack
下一篇
Day 16--天氣app(二) retrofit
系列文
程式初學:Android與Kotlin30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
4a890039
iT邦新手 5 級 ‧ 2022-04-30 23:08:28

請問有可以開放原始碼參考嗎

Kai iT邦新手 4 級 ‧ 2022-08-01 23:18:41 檢舉

不好意思現在才看到你的留言...
github上面有我當初寫的,不介意很爛的話,歡迎參考:D
https://github.com/Kai2020-tech/weather

4a890039 iT邦新手 5 級 ‧ 2022-09-01 11:46:04 檢舉

好ㄉ謝謝

我要留言

立即登入留言